package src;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class VideoSearchTest {
    private WebDriver driver;
    private WebDriverWait wait;

    public VideoSearchTest(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    private static class Condition {
        String selector;
        String text;

        public Condition(String selector, String text) {
            this.selector = selector;
            this.text = text;
        }
    }

    public void testSearch() throws InterruptedException {
        // 访问待测试网站
        driver.get("https://www.bilibili.com");
        
        // 检查搜索框的存在与可见性并点击
        WebElement navSearchForm = driver.findElement(By.id("nav-searchform"));
        if (!navSearchForm.isDisplayed()) {
            throw new RuntimeException("Error: #nav-searchform is not visible!");
        }
        WebElement navSearchContent = navSearchForm.findElement(By.cssSelector(".nav-search-content"));
        if (!navSearchContent.isDisplayed()) {
            throw new RuntimeException("Error: .nav-search-content is not visible!");
        }
        WebElement navSearchInput = navSearchContent.findElement(By.cssSelector(".nav-search-input"));
        if (!navSearchInput.isDisplayed()) {
            throw new RuntimeException("Error: .nav-search-input is not visible!");
        }
        WebElement searchInput = wait.until(ExpectedConditions.elementToBeClickable(navSearchInput));
        searchInput.click();


        // 输入内容并测试清空输入功能
        Thread.sleep(2000);
        navSearchInput.sendKeys("Cypress框架");
        Thread.sleep(1000);
        WebElement clearButton = navSearchContent.findElement(By.cssSelector(".nav-search-clean"));
        if (!clearButton.isDisplayed()) {
            throw new RuntimeException("Error: .nav-search-clean is not visible!");
        }
        Thread.sleep(1000);
        wait.until(ExpectedConditions.elementToBeClickable(clearButton)).click();
        Thread.sleep(2000);


        // 检查搜索按钮的存在和可见性
        WebElement navSearchButton = driver.findElement(By.cssSelector(".nav-search-btn"));
        if (!navSearchButton.isDisplayed()) {
            throw new RuntimeException("Error: .nav-search-btn is not visible!");
        }


        // 输入内容并点击搜索
        navSearchInput.sendKeys("Python入门");
        Thread.sleep(1000);
        wait.until(ExpectedConditions.elementToBeClickable(navSearchButton)).click();
        Thread.sleep(2000);


        // 将Selenium控制转移到新开启的窗口当中
        Set<String> windowHandles = driver.getWindowHandles();
        String currentHandle = driver.getWindowHandle();
        for (String handle : windowHandles) {
            if (!handle.equals(currentHandle)) {
                driver.switchTo().window(handle);
                break;
            }
        }
        wait.until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("document.body.style.zoom = '0.5'"); // 进行适当缩放从而呈现更多筛选后的结果

        // 点击测试搜索结果页面当中的基本筛选条件
        Thread.sleep(2000);
        WebElement mostPlayedOption = driver.findElement(By.cssSelector(".conditions-order > .search-condition-row > :nth-child(2)"));
        if (!mostPlayedOption.isDisplayed()) {
            throw new RuntimeException("Error: mostPlayedOption is not visible!");
        }
        if (!mostPlayedOption.getText().contains("最多播放")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '最多播放'!");
        }
        mostPlayedOption.click();
        Thread.sleep(2000);

        WebElement latestPostOption = driver.findElement(By.cssSelector(".conditions-order > .search-condition-row > :nth-child(3)"));
        if (!latestPostOption.isDisplayed()) {
            throw new RuntimeException("Error: latestPostOption is not visible!");
        }
        if (!latestPostOption.getText().contains("最新发布")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '最新发布'!");
        }
        latestPostOption.click();
        Thread.sleep(2000);
        
        WebElement mostCommentOption = driver.findElement(By.cssSelector(".conditions-order > .search-condition-row > :nth-child(4)"));
        if (!mostCommentOption.isDisplayed()) {
            throw new RuntimeException("Error: mostCommentOption is not visible!");
        }
        if (!mostCommentOption.getText().contains("最多弹幕")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '最多弹幕'!");
        }
        mostCommentOption.click();
        Thread.sleep(2000);

        WebElement mostStartOption = driver.findElement(By.cssSelector(".conditions-order > .search-condition-row > :nth-child(5)"));
        if (!mostStartOption.isDisplayed()) {
            throw new RuntimeException("Error: mostStartOption is not visible!");
        }
        if (!mostStartOption.getText().contains("最多收藏")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '最多收藏'!");
        }
        mostStartOption.click();
        Thread.sleep(2000);

        WebElement comprehensiveRankingOption = driver.findElement(By.cssSelector(".conditions-order > .search-condition-row > :nth-child(1)"));
        if (!comprehensiveRankingOption.isDisplayed()) {
            throw new RuntimeException("Error: comprehensiveRankingOption is not visible!");
        }
        if (!comprehensiveRankingOption.getText().contains("综合排序")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '最多收藏'!");
        }
        comprehensiveRankingOption.click();
        Thread.sleep(2000);

        WebElement moreOption = driver.findElement(By.cssSelector(".conditions-order > .vui_button--active-shrink"));
        if (!moreOption.isDisplayed()) {
            throw new RuntimeException("Error: moreOption is not visible!");
        }
        if (!moreOption.getText().contains("更多筛选")) {
            throw new RuntimeException("Error: Filter option does not contain the expected text '更多筛选'!");
        }
        moreOption.click();
        Thread.sleep(2000);


        // 日期选项
        List<Condition> dateConditions = new ArrayList<>();
        dateConditions.add(new Condition(".more-conditions > :nth-child(1) > :nth-child(2)", "最近一天"));
        dateConditions.add(new Condition(".more-conditions > :nth-child(1) > :nth-child(3)", "最近一周"));
        dateConditions.add(new Condition(".more-conditions > :nth-child(1) > :nth-child(4)", "最近半年"));
        dateConditions.add(new Condition(".more-conditions > :nth-child(1) > :nth-child(1)", "全部日期"));

        // 时长选项
        List<Condition> timeConditions = new ArrayList<>();
        timeConditions.add(new Condition(".more-conditions > :nth-child(2) > :nth-child(2)", "10分钟以下"));
        timeConditions.add(new Condition(".more-conditions > :nth-child(2) > :nth-child(3)", "10-30分钟"));
        timeConditions.add(new Condition(".more-conditions > :nth-child(2) > :nth-child(4)", "30-60分钟"));
        timeConditions.add(new Condition(".more-conditions > :nth-child(2) > :nth-child(5)", "60分钟以上"));
        timeConditions.add(new Condition(".more-conditions > :nth-child(2) > :nth-child(1)", "全部时长"));

        // 外层遍历视频时长日期的筛选条件
        for (Condition dateCondition : dateConditions) {
            WebElement dateElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(dateCondition.selector)));
            if (!dateElement.getText().contains(dateCondition.text)) {
                throw new RuntimeException("Error: Date filter text does not match the expected value!");
            }
            dateElement.click();
            Thread.sleep(2000);

            // 内层遍历视频时长筛选条件
            for (Condition timeCondition : timeConditions) {
                WebElement timeElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(timeCondition.selector)));
                if (!timeElement.getText().contains(timeCondition.text)) {
                    throw new RuntimeException("Error: Time filter text does not match the expected value!");
                }
                timeElement.click();
                Thread.sleep(2000);
            }
        }
    }
}
